import pandas as pd

import util.mydecorator
import util.lib as ulib

from lp_format import job as format_job

std_df = None
month_dict = None
writer = None
stocks = None

def get_sta_df():
    # 读取统计信息
    std_df = pd.read_excel(ulib.data_path + "stock_sta.xlsx", sheet_name="低分位点跌幅")
    return std_df


# 计算两个时间隔离的月数
def cal_dis_month(d1 : str, d2 : str) -> int:
    y1, m1 = [int(x) for x in d1.split("--")]
    y2, m2 = [int(x) for x in d2.split("--")]

    return (y2 - y1) * 12 + m2 -m1



def built_empty_df():
    return pd.DataFrame({}, columns=['stock','month',
                                    'lp_decrease', 'lp_duration','inc_num',
                                    '买入价格',
                                    '前高日期','前高间隔','前高价格','前高跌幅',
                                    '最高日期','最高间隔','最高价格','涨幅',
                                    '最低日期','最低间隔','最低价格','跌幅',
                                    '低点涨幅',
                                    '上市月份数'
                                    ])

def cal_by_month(month):
    print(month)

    global writer, month_dict, std_df, stocks

    ret = built_empty_df() 

    for index,row in std_df[std_df['date'] == month].iterrows():
        stock = row['stock']
        close = row["close"]

        # 获取之后的数据
        month_df  = month_dict[stock][month:].head(36)

        # 之前的记录
        pre_month_df = month_dict[stock][:month]

        pre_max_rec = pre_month_df[pre_month_df['close'] == pre_month_df['close'].max()].head(1).iloc[-1]
        pre_max_close = pre_max_rec["close"]

        # 找出价格最大和最小值
        max_rec = month_df[month_df['close'] == month_df['close'].max()].head(1).iloc[0]
        max_close = max_rec['close']

        # 找出价格最小值，时间区间在初始值与最大值之间
        noNewHigh = max_rec.name == month
        if noNewHigh:
            # 后续价格没有超过现在
            min_df = month_df
        else:
            min_df = month_df[:max_rec.name]

        min_rec = min_df[min_df['close'] == min_df['close'].min()].head(1).iloc[0]
        min_close = min_rec['close']

        item = {
            "stock":stock, 
            "month": month,
            "lp_decrease":row['lp_decrease'],
            "lp_duration": row['lp_duration'],
            "inc_num": row['inc_num'],
            "买入价格" : close, 
            "前高日期": pre_max_rec.name, 
            "前高价格": pre_max_close,
            "前高跌幅" : round((close - pre_max_close) / pre_max_close * 100, 2),
            "最高日期" : max_rec.name, 
            "最高价格" : max_close, 
            "涨幅" : round((max_close - close) / close * 100, 2),
            "最低日期" : min_rec.name, 
            "最低价格" : min_close, 
            "跌幅" : round((min_close - close) / close * 100, 2),
            "低点涨幅": round((max_close - min_close) / min_close * 100, 2) if not noNewHigh else 0,
            "上市月份数" : len(pre_month_df),
            "前高间隔" : cal_dis_month(pre_max_rec.name, month),
            "最高间隔" : cal_dis_month(month, max_rec.name),
            "最低间隔" : cal_dis_month(month, min_rec.name)
              }

        ret.loc[len(ret)] = item

    if len(ret) > 0:
        ret = pd.merge(ret, stocks[['name','category']],left_on="stock", right_on="name", how="left")
        ret = ret.drop(columns=['name'])
        ret = ret.sort_values(by=['lp_duration'], ascending=[True])
        ret.to_excel(writer,sheet_name=month)


# 统计信息
def lp_stat():
    data = pd.read_excel(ulib.data_path + "lp.xlsx", sheet_name=None)

    for month, df in data.items():
        print(month , '记录数', len(df),
              '前高间隔', round(df['前高间隔'].mean(), 2),
              '最高间隔', round(df['最高间隔'].mean(), 2),
              '涨幅', round(df['涨幅'].mean(), 2)
              )



years = ["2018","2019","2020","2021","2022","2023","2024","2025"]
months = ["01","02","03","04","05","06","07","08","09","10","11","12"]

@util.mydecorator.calTime
def job():
    global writer, month_dict, std_df,stocks

    writer = pd.ExcelWriter(ulib.data_path + "lp.xlsx")

    std_df = get_sta_df()

    month_dict = ulib.lib_get_month_data()

    stocks = ulib.lib_get_all_stock()[['name','category']]

    global years, months
    for year in years:
        for month in months:
            cal_by_month(year + "--" + month)

    writer.save()


if __name__ == "__main__":
    job()
    #lp_stat()
    format_job()